/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package me.zhengjie.suli.location.service.impl;

import me.zhengjie.suli.inventory.domain.Inventory;
import me.zhengjie.suli.inventory.repository.InventoryRepository;
import me.zhengjie.suli.location.domain.Location;
import me.zhengjie.util.UuidUtil;
import me.zhengjie.util.Variable;
import me.zhengjie.utils.ValidationUtil;
import me.zhengjie.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import me.zhengjie.suli.location.repository.LocationRepository;
import me.zhengjie.suli.location.service.LocationService;
import me.zhengjie.suli.location.service.dto.LocationDto;
import me.zhengjie.suli.location.service.dto.LocationQueryCriteria;
import me.zhengjie.suli.location.service.mapstruct.LocationMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;

import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
 * @author WYH
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2024-02-05
 **/
@Service
@RequiredArgsConstructor
public class LocationServiceImpl implements LocationService {

    private final LocationRepository locationRepository;
    private final LocationMapper locationMapper;
    private final InventoryRepository inventoryRepository;

    @Override
    public Map<String, Object> queryAll(LocationQueryCriteria criteria, Pageable pageable) {
        Page<Location> page = locationRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(locationMapper::toDto));
    }

    @Override
    public List<LocationDto> queryAll(LocationQueryCriteria criteria) {
        return locationMapper.toDto(locationRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public LocationDto findById(Long id) {
        Location location = locationRepository.findById(id).orElseGet(Location::new);
        ValidationUtil.isNull(location.getId(), "Location", "id", id);
        return locationMapper.toDto(location);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LocationDto create(Location resources) {
        Snowflake snowflake = IdUtil.createSnowflake(1, 1);
        resources.setId(snowflake.nextId());
        return locationMapper.toDto(locationRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Location resources) {
        Location location = locationRepository.findById(resources.getId()).orElseGet(Location::new);
        ValidationUtil.isNull(location.getId(), "Location", "id", resources.getId());
        location.copy(resources);
        locationRepository.save(location);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            locationRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<LocationDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (LocationDto location : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("创建用户", location.getCreateBy());
            map.put("修改用户", location.getUpdateBy());
            map.put("创建日期", location.getCreateTime());
            map.put("修改日期", location.getUpdateTime());
            map.put("是否占用", location.getStatus());
            map.put("库位号", location.getLocationCode());
            map.put("所属仓库", location.getWarehouseCode());
            map.put("库位管理员", location.getLocationAdmin());
            map.put("备注", location.getRemark());
            map.put("排", location.getRow());
            map.put("列", location.getColumn());
            map.put("层", location.getLayer());
            map.put("库位类型", location.getType());
            map.put("身位", location.getBodyPosition());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public List<List<Map<String, Object>>> getLocationUsage(Map<String, String> paramMap) {
        String warehouseCode = paramMap.get("warehouse_code");
        List<List<Map<String, Object>>> columnList = new ArrayList<>();
        String layer = paramMap.get("layerNum");
        if (warehouseCode.equals("常温库")) {
            warehouseCode = "CW%";
            List<Map<String, Object>> locationList = locationRepository.getLocationUsage(warehouseCode, Integer.parseInt(layer));
            int maxCol = (int) locationList.get(0).get("max_row");          // 最大列数（数据库里面写反了） 28
//        int maxRow = (int) locationList.get(0).get("max_col") * 2;          // 最大排数（数据库里面写反了） 5 * 2 区分1，2身位
            int maxRow = 9;          // 最大排数（数据库里面写反了） 区分1，2身位

            /**
             * Allen Gao
             * 修改显示方式 切换排 横轴为列 竖轴为排
             * 2024-04-02
             */
            for (int p = 1; p <= maxRow; p++) {
                List<Map<String, Object>> rowList = new ArrayList<>();
                for (int k = 0; k < locationList.size(); k++) {
                    Map<String, Object> locationMap = locationList.get(k);
                    int bodyPosition = Integer.parseInt(locationMap.get("body_position").toString());
                    int row = (int) locationMap.get("column");
                    if (bodyPosition == 1) {    // 1伸位
                        if (row == 1 || row == 2) {
                            row = row + 1;
                        } else if (row == 3) {
                            row = 5;
                        } else if (row == 4) {
                            row = 8;
                        } else {
                            row = 9;
                        }
                    } else if (bodyPosition == 2) {  // 2伸位
                        if (row == 2) {
                            row = 4;
                        } else if (row == 3) {
                            row = 6;
                        } else if (row == 4) {
                            row = 7;
                        }
                    }
                    if (row == p) {
                        int flag = 0;
                        for (int i = 0; i < rowList.size(); i++) {
                            Map<String, Object> map = rowList.get(i);
                            if (map.get("location_code").equals(locationMap.get("location_code"))) {
                                String str = map.get("material").toString() + "\n" + locationMap.get("material");
                                Map<String, Object> map1 = new HashMap<>(map);
                                map1.put("material", str);
                                flag = 1;
                                rowList.set(i, map1);
                            }
                        }
                        if (flag == 0) {
                            rowList.add(locationMap);
                        }
                    }
                }
                columnList.add(rowList);
            }

        } else {    // 恒温库
            warehouseCode = "HW%";
            List<Map<String, Object>> locationList = locationRepository.getLocationUsage(warehouseCode, Integer.parseInt(layer));
            int maxCol = (int) locationList.get(0).get("max_row");          // 最大列数（数据库里面写反了） 14
            int maxRow = 3;          // 最大排数

            for (int p = 1; p <= maxRow; p++) {
                List<Map<String, Object>> rowList = new ArrayList<>();
                for (int k = 0; k < locationList.size(); k++) {
                    Map<String, Object> locationMap = locationList.get(k);
                    int bodyPosition = Integer.parseInt(locationMap.get("body_position").toString());
                    int row = (int) locationMap.get("column");
                    if (bodyPosition == 2) {  // 2伸位
                        row = 3;
                    }
                    if (row == p) {
                        int flag = 0;
                        for (int i = 0; i < rowList.size(); i++) {
                            Map<String, Object> map = rowList.get(i);
                            if (map.get("location_code").equals(locationMap.get("location_code"))) {
                                String str = map.get("material").toString() + "\n" + locationMap.get("material");
                                Map<String, Object> map1 = new HashMap<>(map);
                                map1.put("material", str);
                                flag = 1;
                                rowList.set(i, map1);
                            }
                        }
                        if (flag == 0) {
                            rowList.add(locationMap);
                        }
                    }
                }
                columnList.add(rowList);
            }

        }

        return columnList;
    }

}